package com.xiaoyu.lanling.feature.push;

import android.content.Context;
import android.os.Bundle;
import android.text.TextUtils;


import com.xiaoyu.base.app.App;
import com.xiaoyu.base.app.AppContext;
import com.xiaoyu.base.app.AppEngine;
import com.xiaoyu.base.data.UserData;
import com.xiaoyu.base.event.BaseEvent;
import com.xiaoyu.base.event.NoReceiverJsonEvent;
import com.xiaoyu.base.net.RequestCreator;
import com.xiaoyu.base.push.IPushEventListener;
import com.xiaoyu.base.push.PushConstants;
import com.xiaoyu.lanling.common.config.HttpConfig;
import com.xiaoyu.lanling.event.push.NewMessageEvent;
import com.xiaoyu.lanling.router.deeplink.DeepLinkRouter;

import androidx.annotation.Nullable;
import androidx.core.app.NotificationManagerCompat;

import in.srain.cube.concurrent.AppThreads;
import in.srain.cube.concurrent.SimpleTask;
import in.srain.cube.request.JsonData;
import in.srain.cube.request.RequestData;
import in.srain.cube.util.CLog;
import in.srain.cube.util.UTUtil;

public class PushData implements IPushEventListener {

    private static final String TAG = "PushData";
    private static final String ACTION_NEW_MESSAGE = "new_message";
    private static final int SYNC_INTERVAL = 60 * 1000 * 3;
    private static PushData sInstance;
    private String mPushType = "";
    private String mToken = "";
    private String mAlternatePushType = PushConstants.PUSH_TYPE_XIAOMI;
    private String mAlternateToken = "";
    private String mDenyPushType = PushConstants.PUSH_TYPE_DENY;
    private String mDenyToken = "unknown";

    private long mLastSyncTime = 0;

    private PushData() {
    }

    public static synchronized PushData getInstance() {
        if (sInstance == null) {
            sInstance = new PushData();
        }
        return sInstance;
    }

    @Override
    public void onRegisterSuccess(String pushType, String pushToken) {
        CLog.d(TAG, "onRegisterSuccess: %s %s", pushType, pushToken);
        mPushType = pushType;
        mToken = pushToken;

        tryToSyncPushToken(true);
    }

    @Override
    public void onRegisterAlternateSuccess(String alternatePushType, String alternatePushToken) {
        CLog.d(TAG, "onRegisterAlternateSuccess: %s %s", alternatePushType, alternatePushToken);
        mAlternatePushType = alternatePushType;
        mAlternateToken = alternatePushToken;

        tryToSyncPushToken(true);
    }

    @Override
    public void onRegisterFail(String pushType, String errorMsg) {
        CLog.d(TAG, "onRegisterFail: %s %s", pushType, errorMsg);
    }

    @Override
    public void onPassThroughMessage(String pushType, String msg) {
        CLog.d(TAG, "onPassThroughMessage: %s %s", pushType, msg);
        AppThreads.runOnDBThread(new SimpleTask() {
            private BaseEvent mBaseEvent;

            @Override
            public void doInBackground() {
                mBaseEvent = createEvent(msg);
            }

            @Override
            public void onFinish(boolean canceled) {
                CLog.d(TAG, "onPassThroughMessage, event post: %s %s %s", pushType, msg, mBaseEvent);
                if (mBaseEvent != null) {
                    mBaseEvent.post();
                }
            }
        });
    }

    private BaseEvent createEvent(String rawText) {
        JsonData data = JsonData.create(rawText);
        JsonData action = data.optJson("action");
        String actionName = action.optString("name");
        JsonData actionPayload = action.optJson("payload");
        if (TextUtils.equals(actionName, ACTION_NEW_MESSAGE)) {
            return new NewMessageEvent(actionPayload);
        }
        return null;
    }

    @Override
    public void onNotificationClickData(String pushType, String data) {
        CLog.d(TAG, "onNotificationClickData: %s %s", pushType, data);
    }

    private boolean hasPermission() {
        return NotificationManagerCompat.from(AppContext.getContext()).areNotificationsEnabled();
    }

    public String getPushType() {
        return hasPermission() ? mPushType : mDenyPushType;
    }

    public String getToken() {
        return hasPermission() ? mToken : mDenyToken;
    }

    public String getAlternatePushType() {
        return hasPermission() ? mAlternatePushType : mDenyPushType;
    }

    public String getAlternateToken() {
        return hasPermission() ? mAlternateToken : mDenyToken;
    }

    void readPush(String pushId, String eventName, String param) {
        if (!TextUtils.isEmpty(pushId)) {
            Bundle params = new Bundle();
            params.putString("pushId", pushId);
            UTUtil.getInstance().logEvent("push_evoke", params);

            Bundle params2 = new Bundle();
            params2.putString("createFrom", param);
            UTUtil.getInstance().logEvent(eventName, params2);

            UTUtil.getInstance().flushLogEvent();
        }
    }

    public void dispatchUrl(@Nullable Context context, String url) {
        if (AppEngine.getInstance().hasFinishedInitialJob()) {
            if (context == null) {
                context = App.getInstance().getTopActivity();
            }
            if (context == null) {
                context = AppContext.getContext();
            }
            DeepLinkRouter.getInstance().dispatch(context, url);
        } else {
            AppEngine.getInstance().addFinishInitialJobCallback(() -> {
                DeepLinkRouter.getInstance().dispatch(AppContext.getContext(), url);
            });
        }
    }

    public void tryToSyncPushToken(boolean force) {
        if (!UserData.getInstance().hasLogin()) {
            return;
        }
        if ((System.currentTimeMillis() - mLastSyncTime < SYNC_INTERVAL) && !force) {
            return;
        }
        mLastSyncTime = System.currentTimeMillis();
        syncPushToken();
    }

    public static void syncPushToken() {
        final String pushType = PushData.getInstance().getPushType();
        final String pushToken = PushData.getInstance().getToken();
        final String alternatePushType = PushData.getInstance().getAlternatePushType();
        final String alternatePushToken = PushData.getInstance().getAlternateToken();
        if (TextUtils.isEmpty(pushType) || TextUtils.isEmpty(pushToken)) {
            return;
        }
        RequestCreator.create(new Object(), NoReceiverJsonEvent.class)
                .setRequestUrl(HttpConfig.LANLING_UPLOAD_PUSH_TOKEN)
                .addPostData("tokenType", pushType)
                .addPostData("pushToken", pushToken)
                .addPostData("alternateTokenType", alternatePushType)
                .addPostData("alternatePushToken", alternatePushToken)
                .enqueue();
    }
}
